//
//  UTEPedDB.m
//  uteped_sdk
//
//  Created by mateng on 2024/2/27.
//

#import <UTEBluetoothRYApi/UTEBluetoothRYApi.h>
#import "UTEPedDB.h"
#import "Table.h"
#import "SleepModel.h"
#import "StressModel.h"
#import "WorkoutModel.h"
#import "HeartRateModel.h"
#import "Spo2Model.h"
#import "StepModel.h"


#define DB_NAME         @"uteped_db.db"
#define SLEEP_TABLE     @"sleep"
#define STRESS_TABLE    @"stress"
#define HART_RATE_TABLE @"heart_rate"
#define SPO2_TABLE      @"spo2"
#define STEP_TABLE      @"step"
#define WORKOUT_TABLE   @"workout"


@interface UTEPedDB ()

@property(nonatomic, strong) NSMutableDictionary *tables;

- (void)initTables;

@end

@implementation UTEPedDB

static UTEPedDB* instance = nil;

+ (UTEPedDB*) shareInstance
{
    if ( instance == nil ) {
        instance = [[UTEPedDB alloc] initWithName:DB_NAME];
    }
    return instance;
}

- (id)initWithName:(NSString *)dbName {
    if (self = [super initWithName:dbName]) {
        self.tables = [[NSMutableDictionary alloc] init];
        [self initTables];
    }
    
    return self;
}

- (void)initTables {
    [self.tables setObject:[[Table alloc] initWithName:SLEEP_TABLE db:self.db] forKey:SLEEP_TABLE];
    [self.tables setObject:[[Table alloc] initWithName:STRESS_TABLE db:self.db] forKey:STRESS_TABLE];
    [self.tables setObject:[[Table alloc] initWithName:HART_RATE_TABLE db:self.db] forKey:HART_RATE_TABLE];
    [self.tables setObject:[[Table alloc] initWithName:SPO2_TABLE db:self.db] forKey:SPO2_TABLE];
    [self.tables setObject:[[Table alloc] initWithName:STEP_TABLE db:self.db] forKey:STEP_TABLE];
    [self.tables setObject:[[Table alloc] initWithName:WORKOUT_TABLE db:self.db] forKey:WORKOUT_TABLE];
}

- (void)saveSleepData:(NSInteger)startTime endTime:(NSInteger)endTime models:(nonnull NSArray *)array address:(NSString*)address{
    
    NSMutableArray *sleepData = [[NSMutableArray alloc] init];
    for (int i = 0; i < array.count; i++) {
        UTEModelSciSleepFileData *model = array[i];
        SleepModel *sleepModel = [[SleepModel alloc] initWithAddress:address];
        [sleepModel from:model];
        [sleepData addObject: sleepModel];
    }
    
    Table *table = [self.tables objectForKey:SLEEP_TABLE];
    [table deleteData:startTime endTime:endTime address:address];
    [table saveData:sleepData];
}

- (void)saveStressData:(NSInteger)startTime endTime:(NSInteger)endTime models:(nonnull NSArray *)array address:(NSString*)address{
    NSMutableArray *stressData = [[NSMutableArray alloc] init];
    for (int i = 0; i < array.count; i++) {
        UTEModeStressOneData *model = array[i];
        StressModel *stressModel = [[StressModel alloc] initWithAddress:address];
        [stressModel from:model];
        [stressData addObject: stressModel];
    }
    
    Table *table = [self.tables objectForKey:STRESS_TABLE];
    [table deleteData:startTime endTime:endTime address:address];
    [table saveData:stressData];
}

- (void)updateWorkoutDetailData:(NSString *)detailStr startTime:(NSString *)startime address:(NSString *)address {
    Table *table = [self.tables objectForKey:WORKOUT_TABLE];
    NSString *setSql = @"detail_data = ?";
    NSString *where = @"start_time = ? and address = ?";
    
    NSArray *args = [NSArray arrayWithObjects: detailStr, startime, address, nil];
    [table updateData:setSql where:where withArgumentsInArray:args];
}

- (void)updateWorkoutGpsData:(NSString*)gpsStr startTime:(NSString*)startime address:(NSString*)address {
    Table *table = [self.tables objectForKey:WORKOUT_TABLE];
    NSString *setSql = @"gps_data = ?";
    NSString *where = @"start_time = ? and address = ?";
            
    NSArray *args = [NSArray arrayWithObjects: gpsStr, startime, address, nil];
    [table updateData:setSql where:where withArgumentsInArray:args];
}

- (void)saveWorkoutData:(NSInteger)startTime endTime:(NSInteger)endTime models:(nonnull NSArray *)array address:(NSString*)address{
    NSMutableArray *workoutData = [[NSMutableArray alloc] init];
    for (int i = 0; i < array.count; i++) {
        UTEModeSportRecordSummary *model = array[i];
        WorkoutModel *workoutModel = [[WorkoutModel alloc] initWithAddress:address];
        [workoutModel from:model];
        [workoutData addObject: workoutModel];
    }
    
    Table *table = [self.tables objectForKey:WORKOUT_TABLE];
    
    NSString *st = [DateUtils timeStampToString:startTime fmt:FMT_TIME_CLANDER];
    NSString *et = [DateUtils timeStampToString:endTime fmt:FMT_TIME_CLANDER];
    NSString *where = @"calendar >= ? and calendar <= ? and address = ? and (sport_id is null or sport_id = 0)";
    
//    NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:st, @"calendar", et, @"calendar", address, @"address", nil];
    NSArray *args = [NSArray arrayWithObjects: st, et, address, nil];
    [table deleteData:where withArgumentsInArray:args];
//    [table deleteData:startTime endTime:endTime address:address];
    [table saveData:workoutData];
}

- (void)saveFitnessData:(NSInteger)startTime endTime:(NSInteger)endTime frameItems:(nonnull NSArray *)frameItems address:(NSString*)address{
    
    NSMutableArray *heartRateData = [[NSMutableArray alloc] init];
    NSMutableArray *spo2Data = [[NSMutableArray alloc] init];
    NSMutableArray *stepData = [[NSMutableArray alloc] init];
    for (int i = 0; i < frameItems.count; i++) {
        UTEModelMotionFrame *frameModel = frameItems[i];
        NSMutableArray<UTEModelMotionFrameItem *> *frameItemList = frameModel.frameItemList;
        for (int j = 0; j < frameItemList.count;j++) {
            UTEModelMotionFrameItem *frameItemModel = frameItemList[j];
            HeartRateModel *hrModel = [[HeartRateModel alloc] initWithAddress:address];
            [hrModel from:frameModel frameItem:frameItemModel];
            if ([hrModel validateValue]) {
                [heartRateData addObject:hrModel];
            }
            
            Spo2Model *spo2Model = [[Spo2Model alloc] initWithAddress:address];
            [spo2Model from:frameModel frameItem:frameItemModel];
            if ([spo2Model validateValue]) {
                [spo2Data addObject:spo2Model];
            }
            
            StepModel *stepModel = [[StepModel alloc] initWithAddress:address];
            [stepModel from:frameModel frameItem:frameItemModel];
            if ([stepModel validateValue]) {
                [stepData addObject:stepModel];
            }
            
        }
    }
    
    Table *table = [self.tables objectForKey:HART_RATE_TABLE];
    BOOL delete = [table deleteData:startTime endTime:endTime address:address];
    [table saveData:heartRateData];
    
    table = [self.tables objectForKey:SPO2_TABLE];
    delete = [table deleteData:startTime endTime:endTime address:address];
    [table saveData:spo2Data];
    
    table = [self.tables objectForKey:STEP_TABLE];
    delete = [table deleteData:startTime endTime:endTime address:address];
    [table saveData:stepData];
}

- (void)removeData:(nonnull NSString *)address {
    NSString *where = @" address = ?";
    for (NSString *key in self.tables) {
        Table *table = self.tables[key];
        [table deleteData:where withArgumentsInArray:[NSArray arrayWithObjects:address, nil]];
    }
}

@end
